package com.example.receiver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONObject;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.util.Log;

public class Router extends Activity {

	ArrayList<LatLng> mMarkerPointsRe = new ArrayList<LatLng>();
	GoogleMap Mapp;
	LatLng Cur;
	LatLng Des;

	public Router() {

	}

	public Router(GoogleMap Mapp, LatLng CurParam, LatLng Des) {
		this.Mapp = Mapp;
		this.Cur = CurParam;
		this.Des = Des;
		Log.d("CurParam", ""+CurParam);
		// this.mMarkerPointsRe = mMarkerPointsReParam;
		drawMarker(this.Cur, this.Des);
	}

	public void drawMarker(LatLng starpoint, LatLng desPoint) {

		mMarkerPointsRe.add(starpoint);
		Log.d("mMarkerPointsRe", "" + mMarkerPointsRe);

		MarkerOptions options = new MarkerOptions();
		options.position(starpoint);
		Log.d("starpoint", "" + starpoint);
		Log.d("options", "" + options);

		if (mMarkerPointsRe.size() == 1) {
			this.Mapp.animateCamera(CameraUpdateFactory.newLatLngZoom(
					starpoint, 12.0f));
			Log.d(" this.Mapp", "" + this.Mapp);
			options.icon(BitmapDescriptorFactory
					.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
			this.Mapp.addMarker(options);

		}

		mMarkerPointsRe.add(desPoint);
		options.position(desPoint);
		Log.d("mMarkerPointsRe1", "" + mMarkerPointsRe);

		if (mMarkerPointsRe.size() == 2) {
			options.icon(BitmapDescriptorFactory
					.defaultMarker(BitmapDescriptorFactory.HUE_RED));
			this.Mapp.addMarker(options);

		}

		if (mMarkerPointsRe.size() >= 2) {

			LatLng origin = mMarkerPointsRe.get(0);
			LatLng dest = mMarkerPointsRe.get(1);
			String url = getDirectionsUrl(origin, dest);
			Log.d("origin",""+origin);
			Log.d("dest",""+dest);
			DownloadTask downloadTask = new DownloadTask();
			downloadTask.execute(url);
		}
	}

	
	private String getDirectionsUrl(LatLng origin, LatLng dest) {

		// Origin of route
		String str_origin = "origin=" + origin.latitude + ","
				+ origin.longitude;

		// Destination of route
		String str_dest = "destination=" + dest.latitude + "," + dest.longitude;

		// Sensor enabled
		String sensor = "sensor=false";

		// Building the parameters to the web service
		String parameters = str_origin + "&" + str_dest + "&" + sensor;

		// Output format
		String output = "json";

		// Building the url to the web service
		String url = "https://maps.googleapis.com/maps/api/directions/"
				+ output + "?" + parameters;

		return url;
	}

	private class DownloadTask extends AsyncTask<String, Void, String> {

		// Downloading data in non-ui thread
		@Override
		protected String doInBackground(String... url) {

			// For storing data from web service
			String data = "";

			try {
				// Fetching the data from web service
				data = downloadUrl(url[0]);
			} catch (Exception e) {
				Log.d("Background Task", e.toString());
			}
			return data;
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);

			ParserTask parserTask = new ParserTask();

			// Invokes the thread for parsing the JSON data
			Log.d("result", ""+result);
			parserTask.execute(result);
			Log.d("result", "result");

		}

	}

	private String downloadUrl(String strUrl) throws IOException {
		String data = "";
		InputStream iStream = null;
		HttpURLConnection urlConnection = null;
		try {
			URL url = new URL(strUrl);

			// Creating an http connection to communicate with url
			urlConnection = (HttpURLConnection) url.openConnection();

			// Connecting to url
			urlConnection.connect();

			// Reading data from url
			iStream = urlConnection.getInputStream();

			BufferedReader br = new BufferedReader(new InputStreamReader(
					iStream));

			StringBuffer sb = new StringBuffer();

			String line = "";
			while ((line = br.readLine()) != null) {
				sb.append(line);
			}

			data = sb.toString();

			br.close();

		} catch (Exception e) {
			Log.d("Exception while downloading url", e.toString());
		} finally {
			iStream.close();
			urlConnection.disconnect();
		}
		return data;
	}

	private class ParserTask extends
			AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {

		// Parsing the data in non-ui thread
		@Override
		protected List<List<HashMap<String, String>>> doInBackground(
				String... jsonData) {

			JSONObject jObject;
			List<List<HashMap<String, String>>> routes = null;

			try {
				jObject = new JSONObject(jsonData[0]);
				DirectionsJSONParser parser = new DirectionsJSONParser();

				// Starts parsing data
				routes = parser.parse(jObject);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return routes;
		}

		// Executes in UI thread, after the parsing process
		@Override
		protected void onPostExecute(List<List<HashMap<String, String>>> result) {
			ArrayList<LatLng> points = null;
			PolylineOptions lineOptions = null;

			// Traversing through all the routes
			for (int i = 0; i < result.size(); i++) {
				points = new ArrayList<LatLng>();
				lineOptions = new PolylineOptions();

				// Fetching i-th route
				List<HashMap<String, String>> path = result.get(i);

				// Fetching all the points in i-th route
				for (int j = 0; j < path.size(); j++) {
					HashMap<String, String> point = path.get(j);

					double lat = Double.parseDouble(point.get("lat"));
					double lng = Double.parseDouble(point.get("lng"));
					LatLng position = new LatLng(lat, lng);

					points.add(position);
				}

				// Adding all the points in the route to LineOptions
				lineOptions.addAll(points);
				lineOptions.width(2);
				lineOptions.color(Color.RED);

			}

			// Drawing polyline in the Google Map for the i-th route
			Mapp.addPolyline(lineOptions);
		}
	}
}
